package com.packet.cheng.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;

import java.time.Duration;

/**
 * @author 张在成
 * @version 1.0
 * @Description
 * @Date 2022/12/23 14:37
 * @since 1.0
 */
/*
@Slf4j
@Configuration
public class RabbitMqConfiguration {

    private static ConnectionFactory connectionFactory(String host, int port, String username, String password, String virtualHost, String addresses) {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(host);
        connectionFactory.setPort(port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost(virtualHost);
        connectionFactory.setAddresses(addresses);
        return connectionFactory;
    }

    private static ConnectionFactory connectionFactory2(String username, String password, String virtualHost, String addresses) {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setAddresses(addresses);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost(virtualHost);
        return connectionFactory;
    }

    @Configuration
    static class RedPacketRabbitMQConfig {

        @Bean
        @Primary
        @ConfigurationProperties("spring.rabbitmq.red-rabbitmq")
        public RabbitProperties redRabbitProperties() {
            return new RabbitProperties();
        }

        @Bean("redRabbitConnectionFactory")
        @Primary
        public ConnectionFactory hireRabbitConnectionFactory(
                @Autowired @Qualifier("redRabbitProperties") RabbitProperties hireRabbitProperties) {
            ConnectionFactory connectionFactory = connectionFactory2(
                    hireRabbitProperties.getUsername(),
                    hireRabbitProperties.getPassword(),
                    hireRabbitProperties.getVirtualHost(),
                    hireRabbitProperties.getAddresses());
            return connectionFactory;
        }

        @Bean("redRabbitContainerFactory")
        public SimpleRabbitListenerContainerFactory hireRabbitListenerContainerFactory(
                SimpleRabbitListenerContainerFactoryConfigurer configurer,
                @Autowired @Qualifier("redRabbitConnectionFactory") ConnectionFactory redRabbitConnectionFactory
        ) {
            SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
            configurer.configure(factory, redRabbitConnectionFactory);
            return factory;
        }

        @Configuration
        static class RedRabbitTemplateConfiguration {

            private final RabbitProperties properties;

            public RedRabbitTemplateConfiguration(
                    RabbitProperties hireRabbitProperties) {
                this.properties = hireRabbitProperties;
            }

            @Bean("redRabbitTemplate")
            @Primary
            public RabbitTemplate hireRabbitTemplate(
                    @Autowired @Qualifier("redRabbitConnectionFactory") ConnectionFactory hireRabbitConnectionFactory) {
                PropertyMapper map = PropertyMapper.get();
                RabbitTemplate template = new RabbitTemplate(hireRabbitConnectionFactory);
                template.setMessageConverter(new Jackson2JsonMessageConverter());
                template.setMandatory(determineMandatoryFlag());
                RabbitProperties.Template activityProperties = this.properties.getTemplate();
                if (activityProperties.getRetry().isEnabled()) {
                    template.setRetryTemplate(createRetryTemplate(activityProperties.getRetry()));
                }
                map.from(activityProperties::getReceiveTimeout).whenNonNull().as(Duration::toMillis)
                        .to(template::setReceiveTimeout);
                map.from(activityProperties::getReplyTimeout).whenNonNull().as(Duration::toMillis)
                        .to(template::setReplyTimeout);
                map.from(activityProperties::getExchange).to(template::setExchange);
                map.from(activityProperties::getRoutingKey).to(template::setRoutingKey);
                return template;
            }

            private boolean determineMandatoryFlag() {
                Boolean mandatory = this.properties.getTemplate().getMandatory();
                return (mandatory != null) ? mandatory : this.properties.isPublisherReturns();
            }

            private RetryTemplate createRetryTemplate(RabbitProperties.Retry properties) {
                PropertyMapper map = PropertyMapper.get();
                RetryTemplate template = new RetryTemplate();
                SimpleRetryPolicy policy = new SimpleRetryPolicy();
                map.from(properties::getMaxAttempts).to(policy::setMaxAttempts);
                template.setRetryPolicy(policy);
                ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
                map.from(properties::getInitialInterval).whenNonNull().as(Duration::toMillis)
                        .to(backOffPolicy::setInitialInterval);
                map.from(properties::getMultiplier).to(backOffPolicy::setMultiplier);
                map.from(properties::getMaxInterval).whenNonNull().as(Duration::toMillis)
                        .to(backOffPolicy::setMaxInterval);
                template.setBackOffPolicy(backOffPolicy);
                return template;
            }

        }
    }
}
*/
